#pragma once
#ifndef __G_WORKER_THREAD_H__
#define __G_WORKER_THREAD_H__

#include "GTypes.h"
#include "GThread.h"
#include "GEvent.h"

namespace GThread { class GSemaphore; }

namespace GEngine
{
	class GTaskQueue;
	class GTaskResult;

	class GWorkerThread
	{
	friend class GTaskManager;

	typedef GThread::GEvent Event;
	typedef GThread::GSemaphore Semaphore;

	private:
		GSize				Id;
		GTaskQueue*			Queue;

		GTaskResult*		CurrentResult;

		bool				MainThread;
		GThread::GThread	Thread;

		GThread::GEvent		Idle;
		Semaphore*			Active;

		void				GoIdle();

	public:
							GWorkerThread();
							~GWorkerThread();

		GSize				GetId() const;
		GTaskQueue*			GetQueue() const;

		bool				IsMainThread() const;
		
		GUInt32				Start();
		
		bool				Execute(GTaskResult* MyResult = nullptr);

		bool				AttachMainThread(GTaskQueue* MyQueue);

		bool				Create(GSize MyId, GTaskQueue* MyQueue, GThread::GSemaphore* ActiveSem, GThread::GEvent** OutIdle);
		void				Release();

		static GSize		GetCurrentWorkerId();
		static GWorkerThread* GetCurrentWorker();
	};

#define mGCurrentWorker		GWorkerThread::GetCurrentWorker()
#define mGCurrentWorkerId	GWorkerThread::GetCurrentWorkerId()

}


#endif